using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using DG.Tweening;
using UnityEngine;

public class BallBehaviour : MonoBehaviour
{
	public delegate void BallEventHandler();

	private static BallBehaviour instance;

	private static GameObject parentObject;

	public LayerMask obstaclesLayers;

	public LayerMask terrainLayers;

	public LayerMask noVerticalCameraLayers;

	private List<GameObject> noVerticalContacts;

	private List<Collider> currentContacts;

	[HideInInspector]
	public SphereCollider theCollider;

	public LayerMask soundRollFloorLayers;

	public LayerMask soundRollPipeLayers;

	private float soundRollVolume;

	private float soundRollPitch = 1f;

	public bool braking;

	public bool initState = true;

	public bool isActive = true;

	[HideInInspector]
	public Vector3 heading = Vector3.forward;

	public float velocityMagnitude;

	public Vector3 velocity = Vector3.zero;

	public float angularVelocityMagnitude;

	public Vector3 angularVelocity = Vector3.zero;

	private GameObject brakeRelativeObject;

	private float freeFallStartY = -9999f;

	private bool freeFallStarted;

	public bool dying;

	private float fps = 60f;

	private float fpsUpdateInterval = 0.5f;

	private float fpsAccum;

	private int fpsFrames;

	private float fpsTimeleft = 0.5f;

	private int fingerStationary;

	private float fingerStationaryMagnitudeLimit = 2f;

	private float fingerStationaryMagnitudeLimitBeforeBrake = 4f;

	private int inAir;

	private bool isGrounded;

	private bool isOnSlippery;

	public bool isAirborne;

	private int airborneDirection;

	private int airborneFrameLimit = 5;

	private Vector3 previousPosition;

	private GameObject auxGO;

	[HideInInspector]
	public float screenTouchMultiplier = 1f;

	[HideInInspector]
	public float screenTouchLimit = 1000f;

	private float keyboardForwardForcePower;

	private float keyboardForwardForcePowerMax = 80f;

	private float keyboardBackwardForcePower;

	private float keyboardBackwardForcePowerMax = 80f;

	private bool autoBraking;

	private float autoBrakeLerp;

	private float autoBrakeSpeedTarget;

	private List<GameObject> listOfLineRenderers;

	public bool processTouch;

	private bool fingerOnScreen;

	private bool haveCurrentValues;

	private Vector3 currentTouchStartPosition;

	private Vector3 currentTouchPosition;

	private bool havePrevValues;

	private Vector3 prevTouchPosition;

	private bool touchBegan;

	private bool recordTouch;

	private Vector3 recordTouchPosition;

	private Utils.TouchState recordTouchState;

	private Tweener levelEndTween;

	[method: MethodImpl(32)]
	public static event BallEventHandler BallResetEvent;

	[method: MethodImpl(32)]
	public static event BallEventHandler BallResumedEvent;

	[method: MethodImpl(32)]
	public static event BallEventHandler BallFirstMoveEvent;

	[method: MethodImpl(32)]
	public static event BallEventHandler BallWillDieEvent;

	[method: MethodImpl(32)]
	public static event BallEventHandler BallLiftOffEvent;

	[method: MethodImpl(32)]
	public static event BallEventHandler BallInAirPeakedEvent;

	[method: MethodImpl(32)]
	public static event BallEventHandler BallLandedEvent;

	public static BallBehaviour GetInstance()
	{
		if (!instance)
		{
			parentObject = GameObject.Find("TheBall");
			if (parentObject != null)
			{
				instance = parentObject.GetComponent<BallBehaviour>();
			}
		}
		return instance;
	}

	public static void FireBallReset()
	{
		if (BallBehaviour.BallResetEvent != null)
		{
			BallBehaviour.BallResetEvent();
		}
	}

	public static void FireBallResumed()
	{
		if (BallBehaviour.BallResumedEvent != null)
		{
			BallBehaviour.BallResumedEvent();
		}
	}

	public static void FireBallFirstMove()
	{
		if (BallBehaviour.BallFirstMoveEvent != null)
		{
			BallBehaviour.BallFirstMoveEvent();
		}
	}

	public static void FireBallWillDie()
	{
		if (BallBehaviour.BallWillDieEvent != null)
		{
			BallBehaviour.BallWillDieEvent();
		}
	}

	public static void FireBallLiftOff()
	{
		if (BallBehaviour.BallLiftOffEvent != null)
		{
			BallBehaviour.BallLiftOffEvent();
		}
	}

	public static void FireBallInAirPeaked()
	{
		if (BallBehaviour.BallInAirPeakedEvent != null)
		{
			BallBehaviour.BallInAirPeakedEvent();
		}
	}

	public static void FireBallLanded()
	{
		if (BallBehaviour.BallLandedEvent != null)
		{
			BallBehaviour.BallLandedEvent();
		}
	}

	private void Awake()
	{
		base.GetComponent<Rigidbody>().isKinematic = true;
		processTouch = false;
	}

	private void Start()
	{
		Audio.followTarget = base.gameObject;
		if (auxGO == null)
		{
			auxGO = new GameObject("Auxiliary GameObject");
		}
		currentContacts = new List<Collider>();
		noVerticalContacts = new List<GameObject>();
		braking = false;
		initState = true;
		theCollider = base.gameObject.GetComponent<SphereCollider>();
		base.GetComponent<Rigidbody>().maxAngularVelocity = 53f;
		screenTouchMultiplier = Utils.GetScreenTouchMultiplier();
		EventManager.OneTouchBeginEvent += OneTouchBegin;
		EventManager.OneTouchMoveEvent += OneTouchMove;
		EventManager.OneTouchEndEvent += OneTouchEnd;
		EventManager.GameFreezeEvent += OnGameFreeze;
		EventManager.GameUnfreezeEvent += OnGameUnfreeze;
		LevelEnd.LevelEndEnterEvent += OnLevelEnd;
	}

	private void OnDestroy()
	{
		EventManager.OneTouchBeginEvent -= OneTouchBegin;
		EventManager.OneTouchMoveEvent -= OneTouchMove;
		EventManager.OneTouchEndEvent -= OneTouchEnd;
		EventManager.GameFreezeEvent -= OnGameFreeze;
		EventManager.GameUnfreezeEvent -= OnGameUnfreeze;
		LevelEnd.LevelEndEnterEvent -= OnLevelEnd;
	}

	private void OnGameFreeze()
	{
		processTouch = false;
		Audio.StopRollingSound();
	}

	private void OnGameUnfreeze()
	{
		processTouch = true;
	}

	private void OnCollisionEnter(Collision collisionInfo)
	{
		if (base.GetComponent<Rigidbody>().isKinematic)
		{
			return;
		}
		if (currentContacts.IndexOf(collisionInfo.collider) == -1)
		{
			currentContacts.Add(collisionInfo.collider);
		}
		if (Utils.IsInLayerMask(collisionInfo.gameObject, LayerMask.GetMask("TerrainDynamic", "TerrainNoVertical")) && collisionInfo.gameObject.GetComponent<Rigidbody>() != null)
		{
			brakeRelativeObject = collisionInfo.gameObject;
		}
		if (!initState)
		{
			float num = (collisionInfo.relativeVelocity + base.GetComponent<Rigidbody>().velocity).sqrMagnitude * 0.005f;
			float volume = Mathf.Clamp(num, 0f, 1f);
			if (Utils.IsInLayerMask(collisionInfo.gameObject, soundRollPipeLayers))
			{
				Audio.PlaySoundCollisionPipe(volume);
			}
			else
			{
				Audio.PlaySoundCollisionFloor(volume);
			}
			float num2 = 0.01f;
			if (num > num2)
			{
				float shakeDuration = Mathf.Lerp(0f, 0.2f, (num - num2) * 0.5f);
				float shakeMagnitude = Mathf.Lerp(0f, 0.15f, (num - num2) * 0.5f);
				OrbitCamera.GetInstance().Shake(shakeDuration, shakeMagnitude);
				BallGiro.GetInstance().OnObjectCollision(collisionInfo, num - num2);
			}
		}
		if (Utils.IsInLayerMask(collisionInfo.gameObject, noVerticalCameraLayers) && noVerticalContacts.IndexOf(collisionInfo.gameObject) == -1)
		{
			noVerticalContacts.Add(collisionInfo.gameObject);
		}
		if (noVerticalContacts.Count > 0)
		{
			OrbitCamera.GetInstance().lockVertical = true;
		}
		else
		{
			OrbitCamera.GetInstance().lockVertical = false;
		}
		if (OrbitCamera.GetInstance().lateralView)
		{
			OrbitCamera.GetInstance().EndLateralView();
		}
	}

	private void OnCollisionExit(Collision collisionInfo)
	{
		if (currentContacts.IndexOf(collisionInfo.collider) != -1)
		{
			currentContacts.Remove(collisionInfo.collider);
		}
		if (collisionInfo.gameObject == brakeRelativeObject)
		{
			brakeRelativeObject = null;
		}
		if (Utils.IsInLayerMask(collisionInfo.gameObject, noVerticalCameraLayers) && noVerticalContacts.IndexOf(collisionInfo.gameObject) != -1)
		{
			noVerticalContacts.Remove(collisionInfo.gameObject);
		}
		if (noVerticalContacts.Count > 0)
		{
			OrbitCamera.GetInstance().lockVertical = true;
		}
		else
		{
			OrbitCamera.GetInstance().lockVertical = false;
		}
	}

	private void Update()
	{
		float volume = Mathf.Lerp(Audio.rollingSoundVolume, soundRollVolume, Time.deltaTime * 10f);
		float pitch = Mathf.Lerp(Audio.rollingSoundPitch, soundRollPitch, Time.deltaTime * 1f);
		Audio.SetRollingSoundValues(volume, pitch);
		if (Game.gameState == GameState.Paused)
		{
			return;
		}
		if (isAirborne)
		{
			if (!freeFallStarted)
			{
				freeFallStarted = true;
				freeFallStartY = base.transform.position.y;
			}
			else if (!dying)
			{
				if (freeFallStartY - base.transform.position.y > 17f && !base.GetComponent<Rigidbody>().isKinematic)
				{
					dying = true;
					Debug.Log("(" + Time.frameCount + ") Ball: FireBallWillDie " + Game.gameState);
					FireBallWillDie();
				}
			}
			else if (freeFallStartY - base.transform.position.y > 100f && isActive)
			{
				StopMovement();
			}
		}
		else
		{
			freeFallStarted = false;
		}
		UpdateFPS();
	}

	private void UpdateFPS()
	{
		fpsTimeleft -= Time.deltaTime;
		fpsAccum += 1f / Time.unscaledDeltaTime;
		fpsFrames++;
		if (fpsTimeleft <= 0f)
		{
			fps = fpsAccum / (float)fpsFrames;
			fpsTimeleft = fpsUpdateInterval;
			fpsAccum = 0f;
			fpsFrames = 0;
			screenTouchLimit = Utils.GetScreenTouchLimit(true, fps);
		}
	}

	private void FixedUpdate()
	{
		if (!isActive)
		{
			return;
		}
		isGrounded = IsGrounded();
		isOnSlippery = IsOnSlippery();
		SetRollSound(isGrounded);
		if (isGrounded)
		{
			if (isAirborne)
			{
				FireBallLanded();
			}
			inAir = 0;
			isAirborne = false;
		}
		else
		{
			inAir++;
		}
		if (inAir > airborneFrameLimit)
		{
			if (!isAirborne)
			{
				FireBallLiftOff();
				airborneDirection = 1;
			}
			isAirborne = true;
		}
		if (isAirborne)
		{
			int num = (int)Mathf.Sign(base.transform.position.y - previousPosition.y);
			if (airborneDirection >= 0 && num < 0)
			{
				FireBallInAirPeaked();
			}
			airborneDirection = num;
		}
		previousPosition = base.transform.position;
		if (!initState)
		{
			if (velocityMagnitude > 0.001f)
			{
				heading = velocity;
			}
		}
		else
		{
			Vector3 vector = velocity;
			vector.y = 0f;
			if (vector.magnitude > 0.01f)
			{
				heading = velocity;
			}
		}
		if (base.GetComponent<Rigidbody>().isKinematic)
		{
			return;
		}
		base.GetComponent<Rigidbody>().mass = ConfigParams.ballMass;
		base.GetComponent<Rigidbody>().drag = ConfigParams.ballDrag;
		base.GetComponent<Rigidbody>().angularDrag = ConfigParams.ballDrag * 3f;
		velocity = base.GetComponent<Rigidbody>().velocity;
		velocityMagnitude = velocity.magnitude;
		angularVelocity = base.GetComponent<Rigidbody>().angularVelocity;
		angularVelocityMagnitude = angularVelocity.magnitude;
		if (autoBraking)
		{
			Vector3 vector2 = Vector3.Lerp(velocity, Vector3.zero, autoBrakeLerp);
			vector2.y = velocity.y;
			Vector3 vector3 = Vector3.Lerp(angularVelocity, Vector3.zero, autoBrakeLerp);
			base.GetComponent<Rigidbody>().velocity = vector2;
			base.GetComponent<Rigidbody>().angularVelocity = vector3;
			velocity = base.GetComponent<Rigidbody>().velocity;
			velocityMagnitude = velocity.magnitude;
			angularVelocity = base.GetComponent<Rigidbody>().angularVelocity;
			angularVelocityMagnitude = angularVelocity.magnitude;
			if (velocityMagnitude < autoBrakeSpeedTarget)
			{
				autoBraking = false;
			}
		}
		HandleTouch();
		if (isGrounded && !braking)
		{
			Vector3 force = Vector3.down * Mathf.Clamp(base.GetComponent<Rigidbody>().velocity.magnitude, 0f, 10f) * 2f;
			base.GetComponent<Rigidbody>().AddForce(force, ForceMode.Acceleration);
		}
	}

	private void HandleTouch()
	{
		bool flag = false;
		Vector3 touchOffset = Vector3.zero;
		if (haveCurrentValues)
		{
			if (havePrevValues)
			{
				touchOffset = currentTouchPosition - prevTouchPosition;
				touchOffset *= screenTouchMultiplier;
				flag = true;
			}
			prevTouchPosition = currentTouchPosition;
			haveCurrentValues = false;
			havePrevValues = true;
		}
		if (fingerOnScreen)
		{
			if (touchOffset.magnitude < fingerStationaryMagnitudeLimit)
			{
				fingerStationary++;
			}
			else
			{
				fingerStationary = 0;
			}
		}
		else
		{
			fingerStationary = 0;
		}
		if (!flag)
		{
			return;
		}
		bool flag2 = false;
		Vector3 force = Vector3.zero;
		bool flag3 = false;
		Vector3 torque = Vector3.zero;
		float num = Mathf.Clamp(touchOffset.magnitude, 0f, screenTouchLimit) * ConfigParams.touchSensitivity;
		Vector3 directionForTouchOffset = getDirectionForTouchOffset(touchOffset);
		directionForTouchOffset.y = 0f;
		directionForTouchOffset.Normalize();
		if (isGrounded)
		{
			if (isOnSlippery)
			{
				float forcePowerSlippery = ConfigParams.forcePowerSlippery;
				float torquePowerSlippery = ConfigParams.torquePowerSlippery;
				flag2 = true;
				force = directionForTouchOffset * num * forcePowerSlippery;
				flag3 = true;
				torque = Vector3.Cross(Vector3.up, directionForTouchOffset * num * torquePowerSlippery);
			}
			else
			{
				float forcePower = ConfigParams.forcePower;
				float num2 = 1f - Mathf.Tan(Mathf.Clamp(velocityMagnitude, 0f, 23.187023f) / 15f) / 40f;
				flag2 = true;
				force = directionForTouchOffset * num * forcePower;
				auxGO.transform.position = base.GetComponent<Rigidbody>().transform.position;
				auxGO.transform.LookAt(base.GetComponent<Rigidbody>().transform.position + velocity);
				Vector3 position = auxGO.transform.InverseTransformPoint(base.GetComponent<Rigidbody>().transform.position + force);
				if (position.z > 0f)
				{
					position.z = num2 * position.z;
				}
				force = auxGO.transform.TransformPoint(position) - base.GetComponent<Rigidbody>().transform.position;
				if (velocityMagnitude < 0.2f && touchOffset.magnitude < 4f * screenTouchMultiplier)
				{
					float num3 = velocityMagnitude + 0.02f;
					force *= num3;
				}
			}
			braking = false;
			fingerStationaryMagnitudeLimit = fingerStationaryMagnitudeLimitBeforeBrake * screenTouchMultiplier;
		}
		if (isAirborne)
		{
			float forcePowerAir = ConfigParams.forcePowerAir;
			float torquePowerAir = ConfigParams.torquePowerAir;
			flag2 = true;
			force = directionForTouchOffset * num * forcePowerAir;
			flag3 = true;
			torque = Vector3.Cross(Vector3.up, directionForTouchOffset * num * torquePowerAir);
		}
		if (flag2)
		{
			base.GetComponent<Rigidbody>().AddForce(force);
		}
		if (flag3)
		{
			base.GetComponent<Rigidbody>().AddTorque(torque);
		}
	}

	private void HandleKeyboard()
	{
		if (Input.GetKey("up"))
		{
			keyboardForwardForcePower = Mathf.Lerp(keyboardForwardForcePower, keyboardForwardForcePowerMax, 0.1f);
			float num = keyboardForwardForcePower;
			float num2 = 1f - Mathf.Tan(Mathf.Clamp(velocityMagnitude, 0f, 23.187023f) / 15f) / 40f;
			Vector3 force = heading.normalized * num * num2;
			base.GetComponent<Rigidbody>().AddForce(force);
		}
		else
		{
			keyboardForwardForcePower = Mathf.Lerp(keyboardForwardForcePower, 0f, 0.5f);
		}
		if (Input.GetKey("down"))
		{
			keyboardBackwardForcePower = Mathf.Lerp(keyboardBackwardForcePower, keyboardBackwardForcePowerMax, 0.1f);
			float num3 = keyboardBackwardForcePower;
			float num4 = 1f - Mathf.Tan(Mathf.Clamp(velocityMagnitude, 0f, 23.187023f) / 15f) / 40f;
			Vector3 force2 = heading.normalized * num3 * num4 * -1f;
			base.GetComponent<Rigidbody>().AddForce(force2);
		}
		else
		{
			keyboardBackwardForcePower = Mathf.Lerp(keyboardBackwardForcePower, 0f, 0.5f);
		}
		float value = (30f - velocityMagnitude) / 5f;
		value = Mathf.Clamp(value, 0f, 10f);
		if (Input.GetKey("left"))
		{
			Debug.Log(value);
			base.GetComponent<Rigidbody>().velocity = Quaternion.Euler(0f, 0f - value, 0f) * base.GetComponent<Rigidbody>().velocity;
		}
		if (Input.GetKey("right"))
		{
			Debug.Log(value);
			base.GetComponent<Rigidbody>().velocity = Quaternion.Euler(0f, value, 0f) * base.GetComponent<Rigidbody>().velocity;
		}
	}

	public void AutoBrake()
	{
		autoBraking = true;
		autoBrakeLerp = 0.5f;
		autoBrakeSpeedTarget = 0.1f;
		fingerOnScreen = false;
		haveCurrentValues = false;
		touchBegan = false;
	}

	public void Freeze()
	{
		base.GetComponent<Rigidbody>().velocity = Vector3.zero;
		base.GetComponent<Rigidbody>().angularVelocity = Vector3.zero;
		base.GetComponent<Rigidbody>().isKinematic = true;
		base.GetComponent<Rigidbody>().isKinematic = false;
	}

	private IEnumerator DrawLine(Vector3 start, Vector3 finish)
	{
		GameObject lineGO = new GameObject();
		LineRenderer lineRenderer = lineGO.AddComponent<LineRenderer>();
		lineRenderer.SetPosition(0, start);
		lineRenderer.SetPosition(1, finish);
		lineRenderer.SetWidth(0.05f, 0.05f);
		lineRenderer.material = new Material(Shader.Find("Custom/Particles/Additive"));
		lineRenderer.SetColors(Color.white, Color.red);
		lineGO.layer = base.gameObject.layer;
		lineRenderer.sortingOrder = -1;
		yield return new WaitForSeconds(1f);
		Object.Destroy(lineGO);
	}

	private void DrawLineGO(Vector3 start, Vector3 finish)
	{
		GameObject gameObject = new GameObject();
		LineRenderer lineRenderer = gameObject.AddComponent<LineRenderer>();
		lineRenderer.SetPosition(0, start);
		lineRenderer.SetPosition(1, finish);
		lineRenderer.SetWidth(0.05f, 0.05f);
		lineRenderer.material = new Material(Shader.Find("Custom/Particles/Additive"));
		lineRenderer.SetColors(Color.white, Color.red);
		gameObject.layer = base.gameObject.layer;
		lineRenderer.sortingOrder = -1;
		listOfLineRenderers.Add(gameObject);
	}

	public void StopMovement()
	{
		isActive = false;
		base.GetComponent<Rigidbody>().isKinematic = true;
		processTouch = false;
		velocity = Vector3.zero;
		velocityMagnitude = 0f;
		angularVelocity = Vector3.zero;
		angularVelocityMagnitude = 0f;
		SetRollSound(false);
	}

	public void ResumeMovement()
	{
		isActive = true;
		base.GetComponent<Rigidbody>().isKinematic = false;
		processTouch = true;
		touchBegan = false;
		havePrevValues = false;
		haveCurrentValues = false;
		base.GetComponent<Rigidbody>().velocity = Vector3.zero;
		base.GetComponent<Rigidbody>().angularVelocity = Vector3.zero;
		base.GetComponent<Rigidbody>().WakeUp();
		FireBallResumed();
	}

	public void Reset(float resumeDelay = 0.1f)
	{
		KillLevelEndTween();
		FireBallReset();
		StopMovement();
		initState = true;
		dying = false;
		freeFallStarted = false;
		velocity = Vector3.zero;
		velocityMagnitude = 0f;
		angularVelocity = Vector3.zero;
		angularVelocityMagnitude = 0f;
		currentContacts.Clear();
		noVerticalContacts.Clear();
		soundRollVolume = 0f;
		SetToSpawnPoint();
		Invoke("ResumeMovement", resumeDelay);
	}

	public void SetToSpawnPoint()
	{
		GameObject gameObject = SpawnPoint.GetGameObject();
		if ((bool)gameObject)
		{
			base.transform.position = gameObject.transform.position;
			heading = gameObject.transform.forward;
		}
		else
		{
			Debug.Log("nu ar trebui sa ajunga aici ... lasat cazul pentru debug ... whatever");
			base.transform.position = Vector3.up;
			heading = Vector3.forward;
		}
	}

	public void SetToNeutralPosition()
	{
		base.transform.position = new Vector3(10000f, 10000f, 10000f);
		heading = Vector3.forward;
	}

	private bool IsGrounded()
	{
		return Physics.CheckSphere(base.transform.position, theCollider.radius * 1.05f, (int)obstaclesLayers | (int)terrainLayers);
	}

	private bool IsOnSlippery()
	{
		foreach (Collider currentContact in currentContacts)
		{
			if ((bool)currentContact.gameObject && currentContact.gameObject.tag == "slippery")
			{
				return true;
			}
		}
		return false;
	}

	private void SetRollSound(bool isGrounded)
	{
		if (isGrounded)
		{
			GameObject gameObject = null;
			if (currentContacts.Count > 0)
			{
				RollingMode rollingMode = RollingMode.pipe;
				foreach (Collider currentContact in currentContacts)
				{
					if (currentContact != null && Utils.IsInLayerMask(currentContact.gameObject, soundRollFloorLayers))
					{
						rollingMode = RollingMode.floor;
						gameObject = currentContact.gameObject;
						break;
					}
				}
				Audio.SetRollingSoundMode(rollingMode);
			}
			soundRollVolume = velocity.sqrMagnitude / 400f;
			if (gameObject != null && gameObject.GetComponent<Rigidbody>() != null)
			{
				soundRollVolume = (velocity - gameObject.GetComponent<Rigidbody>().velocity).sqrMagnitude / 400f;
			}
			soundRollVolume = Mathf.Clamp(soundRollVolume, 0f, 1f);
			soundRollPitch = Mathf.Lerp(0.8f, 1f, velocity.magnitude / 10f);
		}
		else
		{
			soundRollVolume = 0f;
		}
	}

	private Vector3 getDirectionForTouchOffset(Vector3 touchOffset)
	{
		Vector3 zero = Vector3.zero;
		Camera camera = OrbitCamera.GetInstance().camera;
		Vector3 point = camera.ScreenPointToRay(new Vector3(Screen.width / 2, Screen.height / 2, 0f)).GetPoint(camera.farClipPlane);
		Vector3 up = Vector3.up;
		up = Quaternion.Euler(OrbitCamera.GetInstance().currentAngleVertical - 20f, 0f, 0f) * up;
		up = Quaternion.Euler(0f, OrbitCamera.GetInstance().currentAngleHorizontal, 0f) * up;
		Plane plane = new Plane(up, point);
		Vector3 position = new Vector3(Screen.width / 2, Screen.height / 2, 0f);
		Vector3 position2 = new Vector3(position.x + touchOffset.x, position.y + touchOffset.y, 0f);
		Ray ray = camera.ScreenPointToRay(position);
		float enter;
		plane.Raycast(ray, out enter);
		Vector3 point2 = ray.GetPoint(enter);
		ray = camera.ScreenPointToRay(position2);
		plane.Raycast(ray, out enter);
		Vector3 point3 = ray.GetPoint(enter);
		zero = point3 - point2;
		if (enter < 0f)
		{
			Debug.Log("getDirectionForTouchOffset distanceOnRay < 0" + touchOffset);
			zero *= -1f;
		}
		if (base.GetComponent<Rigidbody>().velocity.magnitude < 0.2f)
		{
			float t = base.GetComponent<Rigidbody>().velocity.magnitude + 0.6f;
			Vector3 forward = OrbitCamera.GetInstance().transform.forward;
			forward.y = 0f;
			zero = Vector3.Lerp(forward, zero, t);
		}
		return zero;
	}

	private void OneTouchBegin(Vector3 touchPosition)
	{
		if (UserInterface.touchCatched || !processTouch || autoBraking)
		{
			return;
		}
		if (listOfLineRenderers != null)
		{
			for (int i = 0; i < listOfLineRenderers.Count; i++)
			{
				Object.Destroy(listOfLineRenderers[i]);
			}
		}
		listOfLineRenderers = new List<GameObject>();
		fingerOnScreen = true;
		touchBegan = true;
		if (initState)
		{
			FireBallFirstMove();
		}
		initState = false;
		braking = false;
		currentTouchPosition = touchPosition;
		currentTouchStartPosition = touchPosition;
		haveCurrentValues = true;
		havePrevValues = false;
		recordTouch = true;
		recordTouchPosition = touchPosition;
		recordTouchState = Utils.TouchState.touchBegin;
	}

	private void OneTouchMove(Vector3 touchPosition)
	{
		if (UserInterface.touchCatched)
		{
			fingerOnScreen = false;
			haveCurrentValues = false;
			touchBegan = false;
		}
		if (!processTouch)
		{
			OneTouchEnd(touchPosition);
		}
		else if (touchBegan)
		{
			if (!havePrevValues)
			{
				havePrevValues = true;
				prevTouchPosition = currentTouchStartPosition;
			}
			currentTouchPosition = touchPosition;
			haveCurrentValues = true;
		}
	}

	private void OneTouchEnd(Vector3 touchPosition)
	{
		if (touchBegan)
		{
			touchBegan = false;
			fingerOnScreen = false;
			braking = false;
			currentTouchPosition = touchPosition;
			haveCurrentValues = true;
			recordTouch = true;
			recordTouchPosition = touchPosition;
			recordTouchState = Utils.TouchState.touchEnd;
		}
	}

	public void SetManualData(Vector3 position_, Quaternion rotation_, Vector3 velocity_, Vector3 angularVelocity_)
	{
		isActive = true;
		base.GetComponent<Rigidbody>().isKinematic = true;
		base.GetComponent<Rigidbody>().MovePosition(position_);
		base.GetComponent<Rigidbody>().MoveRotation(rotation_);
		velocity = velocity_;
		angularVelocity = angularVelocity_;
		velocityMagnitude = velocity.magnitude;
		angularVelocityMagnitude = angularVelocity.magnitude;
	}

	public void GetRecordData(out Vector3 recPosition, out Quaternion recRotation, out Vector3 recVelocity, out Vector3 recAngularVelocity, out bool recTouch, out Vector3 recTouchPosition, out Utils.TouchState recTouchState)
	{
		recPosition = base.GetComponent<Rigidbody>().transform.position;
		recRotation = base.GetComponent<Rigidbody>().transform.rotation;
		recVelocity = velocity;
		recAngularVelocity = angularVelocity;
		recTouch = recordTouch;
		recTouchPosition = recordTouchPosition;
		recTouchState = recordTouchState;
		recordTouch = false;
	}

	private void OnLevelEnd(GameObject levelEnd)
	{
		float y = 0.75f;
		float num = 0.1f;
		float num2 = 0.4f;
		float duration = 1f;
		float num3 = 4f;
		float interval = 0f;
		StopMovement();
		Sequence sequence = DOTween.Sequence();
		sequence.Append(DOTween.To(GetRigidbodyPosition, SetRigidbodyPosition, levelEnd.transform.position + new Vector3(0f, y, 0f), num2).SetEase(Ease.OutCubic));
		sequence.AppendInterval(interval);
		sequence.AppendCallback(LevelEndAnimationFinished);
		sequence.Play();
		if (0 == 0)
		{
			levelEndTween = DOTween.To(GetRigidbodyPosition, SetRigidbodyPosition, new Vector3(0f, 0f - num, 0f), duration).SetAutoKill(false).SetDelay(num2)
				.SetEase(Ease.InOutSine)
				.SetRelative(true)
				.SetLoops(100, LoopType.Yoyo);
		}
		else
		{
			levelEndTween = DOTween.Punch(GetRigidbodyPosition, SetRigidbodyPosition, 0.25f * Vector3.up, num3, 1, 0.95f).SetAutoKill(false).SetDelay(num2);
		}
	}

	public void KillLevelEndTween()
	{
		if (levelEndTween != null)
		{
			levelEndTween.Kill();
		}
		levelEndTween = null;
	}

	private Vector3 GetRigidbodyPosition()
	{
		return base.GetComponent<Rigidbody>().position;
	}

	private void SetRigidbodyPosition(Vector3 newPosition)
	{
		SetManualData(newPosition, base.transform.rotation, velocity, angularVelocity);
	}

	private void LevelEndAnimationFinished()
	{
		Game.FireGameFinishEvent();
	}
}
